package com.hhf.ds.service;

import com.hhf.ds.entity.PageBean;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author haohaifeng
 * @date 2021/1/22 13:56
 */
@Component
public class PageSupport {

    public Object selectOne(JdbcTemplate jdbcTemplate, String sql,Object[] params,Class cla){
        Object result=null;
        try{
            if(params==null||params.length>0){
                result=jdbcTemplate.queryForObject(sql,cla,params);
            }else{
                result=jdbcTemplate.queryForObject(sql,cla);
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }
        return result;
    }

    /**
     * 查询返回List<Map<String,Object>>格式数据,每一个Map代表一行数据，列名为key
     * @param sql  sql语句
     * @param params 填充问号占位符数
     * @return
     */
    public List<Map<String,Object>> queryForMaps(JdbcTemplate jdbcTemplate, String sql, Object[] params){
        try{
            if(params!=null&&params.length>0){
                return jdbcTemplate.query(sql, new ColumnMapRowMapper() {
                    @Override
                    protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
                        return rs.getString(index);
                    }
                }, params);
            }
            return jdbcTemplate.query(sql, new ColumnMapRowMapper() {
                @Override
                protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
                    return rs.getString(index);
                }
            });
        }catch(Exception ex){
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 查询返回实体对象集合
     * @param sql    sql语句
     * @param params 填充sql问号占位符数
     * @param cla    实体对象类型
     * @return
     */
    public List queryForObjectList(JdbcTemplate jdbcTemplate, String sql,Object[] params,final Class cla){
        final List list=new ArrayList();
        try{
            jdbcTemplate.query(sql, new RowCallbackHandler(){
                @Override
                public void processRow(ResultSet rs) {
                    try{
                        List<String> columnNames=new ArrayList<String>();
                        ResultSetMetaData meta=rs.getMetaData();
                        int num=meta.getColumnCount();
                        for(int i=0;i<num;i++){
                            columnNames.add(meta.getColumnLabel(i+1).toLowerCase().trim());
                        }
                        Method[] methods=cla.getMethods();
                        List<String> fields=new ArrayList<String>();
                        for(int i=0;i<methods.length;i++){
                            if(methods[i].getName().trim().startsWith("set")){
                                String f=methods[i].getName().trim().substring(3);
                                f=(f.charAt(0)+"").toLowerCase().trim()+f.substring(1);
                                fields.add(f);
                            }
                        }
                        do{
                            Object obj=null;
                            try{
                                obj=cla.getConstructor().newInstance();
                            }catch(Exception ex){
                                ex.printStackTrace();
                            }
                            for(int i=0;i<num;i++){
                                String objval=rs.getString(i+1);
                                for(int n=0;n<fields.size();n++){
                                    String fieldName=fields.get(n).trim();
                                    if(columnNames.get(i).equals(fieldName.toLowerCase().trim())){
                                        BeanUtils.copyProperty(obj, fieldName, objval);
                                        break;
                                    }
                                }
                            }
                            list.add(obj);
                        }while(rs.next());
                    }catch(Exception ex){
                        ex.printStackTrace();
                    }
                }
            }, params);
        }catch(Exception ex){ex.printStackTrace();}
        if(list.size()<=0){
            return null;
        }
        return list;
    }

    /**
     * 分页查询.
     */
    public PageBean queryByPage(JdbcTemplate jdbcTemplate, String sql, PageBean page) {
        return queryByPage(jdbcTemplate, sql, null,page, null);
    }

    /**
     * 分页查询.
     */
    public PageBean queryByPage(JdbcTemplate jdbcTemplate, String sql, PageBean page, Class clazz) {
        return queryByPage(jdbcTemplate, sql, null,page, clazz);
    }

    /**
     * 查询分页（MySQL数据库）
     */
    public PageBean queryByPage(JdbcTemplate jdbcTemplate, String sql, Object[] params, PageBean page, Class clazz) {
        int pageNum = page.getPageNo();
        int pageSize = page.getPageSize();
        String rowsql = "select count(*) from ("+sql+") t";   //查询总行数sql
        int pages = 0;   //总页数
        int rows = (Integer)selectOne(jdbcTemplate, rowsql, params, Integer.class);  //查询总行数
        //判断页数,如果是页大小的整数倍就为rows/pageRow如果不是整数倍就为rows/pageRow+1
        if (rows % pageSize == 0) {
            pages = rows / pageSize;
        } else {
            pages = rows / pageSize + 1;
        }
        //查询第pageNum页的数据sql语句
        if (pageNum<=1) {
            sql += " limit 0," + pageSize;
        } else {
            sql += " limit " + ((pageNum-1) * pageSize) + "," + pageSize;
        }
        //查询第pageNum页数据
        List list = null;
        if (clazz != null) {
            list = queryForObjectList(jdbcTemplate, sql, params, clazz);
        } else {
            list = queryForMaps(jdbcTemplate, sql, params);
        }
        //设置总记录数
        page.setTotal(rows);
        //设置总页数
        page.setPages(pages);
        //设置当前页数据
        page.setList(list);
        //设置当前页记录数
        page.setSize(list.size());
        return page;
    }
}
